package org.wevil.service.sys;

import org.wevil.entity.log.LogController;
import org.wevil.entity.log.LogLogin;
import org.wevil.params.export.LogControllerEP;
import org.wevil.params.page.LogControllerPP;
import org.wevil.params.page.LogLoginPP;
import org.wevil.repo.LogControllerRepo;
import org.wevil.repo.LogLoginRepo;
import org.wevil.service.sys.DownloadService;
import org.wevil.util.BeanUtil;
import org.wevil.util.page.PageResult;
import org.wevil.util.page.PageResultUtil;
import org.wevil.vo.list.LogControllerListVo;
import org.wevil.vo.list.LogLoginListVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 日志服务
 * */
@Service
@Transactional
public class LogService {

    @Resource
    LogControllerRepo logControllerRepo;
    @Resource
    LogLoginRepo logLoginRepo;
    @Resource
    DownloadService downloadService;

    /** 记录操作日志 */
    public void saveControllerLog(LogController entity){
        logControllerRepo.save(entity);
    }

    /** 记录登录日志 */
    public void saveLoginLog(LogLogin entity){
        logLoginRepo.save(entity);
    }

    /** 操作日志分页 */
    public PageResult<LogControllerListVo> controllerPage(LogControllerPP param) {
        // 要查询的字段
        Integer current = param.getCurrent();
        Integer size = param.getSize();
        String reqClass = param.getReqClass();
        String reqMethod = param.getReqMethod();
        String resCode = param.getResCode();
        String reqIp = param.getReqIp();
        Specification<LogController> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(reqClass)) {
                predicates.add(cb.like(root.get("reqClass").as(String.class), "%" + reqClass + "%"));
            }
            if (StringUtils.isNotBlank(reqMethod)) {
                predicates.add(cb.like(root.get("reqMethod").as(String.class), "%" + reqMethod + "%"));
            }
            if (StringUtils.isNotBlank(resCode)) {
                predicates.add(cb.like(root.get("resCode").as(String.class), "%" + resCode + "%"));
            }
            if (StringUtils.isNotBlank(reqIp)) {
                predicates.add(cb.like(root.get("reqIp").as(String.class), "%" + reqIp + "%"));
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        Sort sort = Sort.by(Sort.Direction.DESC, "ts");
        Pageable pageable = PageRequest.of(current - 1, size, sort);
        Page<LogController> page = logControllerRepo.findAll(specification, pageable);
        // 封装返回数据
        Iterator<LogController> iterator = page.iterator();
        List<LogControllerListVo> voList = new ArrayList<>();
        while (iterator.hasNext()) {
            LogController next = iterator.next();
            LogControllerListVo vo = new LogControllerListVo();
            BeanUtil.copyPropIgnoreNull(next, vo);
            voList.add(vo);
        }
        // 返回
        long total = logControllerRepo.count(specification);
        return PageResultUtil.generateResult(voList, current, size, total);
    }

    /** 登录日志分页 */
    public PageResult<LogLoginListVo> loginPage(LogLoginPP param) {
        // 要查询的字段
        Integer current = param.getCurrent();
        Integer size = param.getSize();
        String username = param.getUsername();
        String tel = param.getTel();
        String password = param.getPassword();
        String reqIp = param.getReqIp();
        String resCode = param.getResCode();
        Specification<LogLogin> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(username)) {
                predicates.add(cb.like(root.get("username").as(String.class), "%" + username + "%"));
            }
            if (StringUtils.isNotBlank(tel)) {
                predicates.add(cb.like(root.get("tel").as(String.class), "%" + tel + "%"));
            }
            if (StringUtils.isNotBlank(password)) {
                predicates.add(cb.like(root.get("password").as(String.class), "%" + password + "%"));
            }
            if (StringUtils.isNotBlank(reqIp)) {
                predicates.add(cb.like(root.get("reqIp").as(String.class), "%" + reqIp + "%"));
            }
            if (StringUtils.isNotBlank(resCode)) {
                predicates.add(cb.like(root.get("resCode").as(String.class), "%" + resCode + "%"));
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        Sort sort = Sort.by(Sort.Direction.DESC, "ts");
        Pageable pageable = PageRequest.of(current - 1, size, sort);
        Page<LogLogin> page = logLoginRepo.findAll(specification, pageable);
        // 封装返回数据
        Iterator<LogLogin> iterator = page.iterator();
        List<LogLoginListVo> voList = new ArrayList<>();
        while (iterator.hasNext()) {
            LogLogin next = iterator.next();
            LogLoginListVo vo = new LogLoginListVo();
            BeanUtil.copyPropIgnoreNull(next, vo);
            voList.add(vo);
        }
        // 返回
        long total = logLoginRepo.count(specification);
        return PageResultUtil.generateResult(voList, current, size, total);
    }

    /** 操作日志导出 */
    public void controllerPageExcel(LogControllerEP param) {
        // 要查询的字段
        String reqClass = param.getReqClass();
        String reqMethod = param.getReqMethod();
        String resCode = param.getResCode();
        String reqIp = param.getReqIp();
        Specification<LogController> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(reqClass)) {
                predicates.add(cb.like(root.get("reqClass").as(String.class), "%" + reqClass + "%"));
            }
            if (StringUtils.isNotBlank(reqMethod)) {
                predicates.add(cb.like(root.get("reqMethod").as(String.class), "%" + reqMethod + "%"));
            }
            if (StringUtils.isNotBlank(resCode)) {
                predicates.add(cb.like(root.get("resCode").as(String.class), "%" + resCode + "%"));
            }
            if (StringUtils.isNotBlank(reqIp)) {
                predicates.add(cb.like(root.get("reqIp").as(String.class), "%" + reqIp + "%"));
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        Sort sort = Sort.by(Sort.Direction.DESC, "ts");
        List<LogController> page = logControllerRepo.findAll(specification, sort);
        // 封装返回数据
        Iterator<LogController> iterator = page.iterator();
        List<LogControllerListVo> voList = new ArrayList<>();
        while (iterator.hasNext()) {
            LogController next = iterator.next();
            LogControllerListVo vo = new LogControllerListVo();
            BeanUtil.copyPropIgnoreNull(next, vo);
            voList.add(vo);
        }
        downloadService.exportList(voList, LogControllerListVo.class, "操作日志.xlsx");
    }
}
